# -*- coding:utf-8 -*-
"""
@Author : 审心
@Time : 2023/4/17 14:16
解析表格数据为商品标题
"""
import time
from dataclasses import dataclass, field
from typing import List, Tuple

import jieba
from DrissionPage import WebPage
from DrissionPage.action_chains import ActionChains
from DrissionPage.commons.keys import Keys
from xlwings import Sheet
import pandas as pd

from autoTask.taobao.taobao_login import Login
from common.logger.log import log_
from common.utils import StrUtil, FileUtil, web_page_util
from common.utils.web_page_util import ActionChain, MockTap, Input, MockMove
from config.core import is_pro


@dataclass
class TargetProduct:
    """
    操作目标商品对象
    Attributes:
        product_id (str): 目标商品id
        title_prefix (str): 标题前缀。
        title_suffix (str): 标题后缀,
        ignore_cuts (List[str], optional): 需要忽略的分词，默认为空列表。
    """
    product_id: str
    title_prefix: str = ""
    title_suffix: str = ""
    competing1: str = ""
    title_max_length: int = 60
    ignore_cuts: List[str] = field(default_factory=list)

    @staticmethod
    def build_by_param(param: dict):
        return TargetProduct(param.get("productId"), param.get("titlePrefix"),
                             param.get("titleSuffix"), param.get("titleMaxLength"),
                             param.get("ignoreCuts"))


@dataclass
class ParseExcelToTitle:
    """
    解析 Excel 表格生成并设置商品标题。
    Attributes:
        sheet (Sheet): 要解析的 Excel 表格 sheet 对象。
        start_row (int): 起始行号(以1开始)。
        title_max_length (int): 标题最大长度
        ignore_keys (List[str], optional): 需要忽略的标题。默认为空列表。
        tb_username(str): 淘宝账号
        tb_password(str): 淘宝密码
        page(WebPage): 页面对象
    """
    sheet: [str]
    target_product_list: List[TargetProduct] = field(default_factory=list)
    start_row: int = 2
    title_max_length: int = 60
    ignore_keys: List[str] = field(default_factory=list)
    tb_username: str = ''
    tb_password: str = ''
    page: WebPage = None
    is_test_execute: bool = False

    def __call__(self, param: dict = None):
        """
        :param param: 重新初始化的变量
        :return:
        """
        # try:
        if param:
            self.by_param_init(param)
        log_.info("开始解析 Excel 表格生成并设置商品标题")
        for i, target in enumerate(self.target_product_list):
            log_.info(f"设置目标商品标题 序号: {i + 1} 相关信息: {target}")
            # 分析出新标题
            new_title = self.parse_action(target)[0]
            # 跳转至首页
            self.go_to_index_view()
            # 设置页面条件
            self.set_view_condition(target)
            # 设置出标题
            self.set_title_action(new_title, target)
        log_.info("解析 Excel 表格生成并设置商品标题完毕")
        # finally:
        #     pass
        # if isinstance(self.sheet, Sheet):
        #     self.sheet.book.app.quit()

    def __post_init__(self):
        self.cache_links = {
            '首页': 'https://myseller.taobao.com/home.htm'
        }
        # if self.page is None and StrUtil.any_blank(self.tb_username, self.tb_password):
        #     raise RuntimeError("在没有页面对象的情况下,必须传入账号密码进行登录")
        if isinstance(self.sheet, str):
            # self.sheet = xlwings.Book(self.sheet).sheets["市场排行版词+延申词"]
            self.sheet = pd.read_excel(self.sheet, sheet_name="补单周期")

    def by_param_init(self, param: dict = None):
        """
        根据传入的字典初始化对象
        :param param: 参数
        :return:
        """
        self.tb_username = param.get('account')
        self.tb_password = param.get('password')
        self.ignore_keys = param.get('blockWords')
        self.is_test_execute = param.get('isTestExecute')
        target_product_map = param.get("targetProductMap")
        if target_product_map is not None:
            self.target_product_list = [TargetProduct.build_by_param(target) for target in target_product_map]

    def parse_action(self, target_product: TargetProduct) -> Tuple[str, str]:
        """
        解析 sheet 操作 利用jieba分词库
        :param target_product 目标商品
        :return: 标题,组成标题使用的分词
        """
        # 初始化词库
        file_path = FileUtil.get_project_root() + r"/autoTask/taobao/sycm/gjc/gjc_hyc_robot/parseExcelToTitle/static" \
                                                  r"/title_dict.txt"
        with open(file_path, 'r', encoding='utf-8') as f:
            jieba.load_userdict(f)
        keyword_list = self.sheet['关键词'].tolist()
        keyword_list = sorted(keyword_list, key=len)
        # 按照关键词的长度升序排列
        title = target_product.title_prefix
        cuts = []
        for item in keyword_list:
            # 过滤单字关键词,删除空格
            # cut_keys = list(filter(lambda x: len(x) > 1, list(jieba.cut(item[0].replace(" ", "")))))
            cut_keys = [word for word in jieba.cut(item.replace(" ", "")) if len(word) > 1]
            # 过滤重复内容的关键词
            cut_keys = StrUtil.filter_substrings(cut_keys)
            # 追加到选用词
            for cut in cut_keys:
                if cut not in cuts:
                    cuts.append(cut)
        # 过滤需要过滤的关键词
        cuts = filter(lambda x: all(ignore not in x for ignore in target_product.ignore_cuts),
                      StrUtil.filter_substrings(cuts))
        use_cuts = []
        # 拼接成为标题
        for cut in cuts:
            if len((title + cut + target_product.title_suffix).encode('gbk')) >= self.title_max_length:
                break
            if cut not in title and cut not in target_product.title_suffix:
                title += cut
                use_cuts.append(cut)
        return title + target_product.title_suffix, " , ".join(use_cuts)

    def set_title_action(self, new_title, target_product: TargetProduct):
        """
        设置标题动作
        :param new_title 新标题
        :param target_product 目标商品对象
        :return:
        """
        total_text = self.page(".next-pagination-total").text
        if total_text != '共1件商品':
            log_.warning(f"没有精确的搜索到目标商品 商品ID: {target_product.product_id} text : {total_text}")
            return
        title_el = self.page("tag:a@@class=title-link")
        MockMove(title_el, before_delay=(1, 2), after_delay=(2, 3),
                 msg="移动鼠标至商品标题")()
        MockTap(title_el.next(), after_delay=(1, 3), msg="打开标题编辑窗", reduce_scope=(5, 5))()
        Input(self.page(".ipt-content")("tag:input"), msg="输入新标题", vals=new_title, after_delay=(2, 3))()
        if not self.is_test_execute:
            MockTap(self.page(".next-dialog-footer next-align-right")("tx:提交"), after_delay=(2, 3))()
        else:
            MockTap(self.page(".next-dialog-footer next-align-right")("tx:取消"), after_delay=(2, 3))()

    def go_to_index_view(self):
        """
        跳转到任务首页
        :return:
        """
        index_url = self.cache_links.get('首页')
        # 登录
        if self.page is None:
            self.page, _ = Login(account=self.tb_username, password=self.tb_password).execute()
        if not self.page.url.startswith(index_url):
            self.page.get(index_url)
            self.page.wait.load_start(timeout=10)
        self.page.refresh()
        self.page.wait.load_start(30)
        ActionChain(self.page)([
            MockTap("tag=span@@text()=商品", before_delay=(2, 3), after_delay=(2, 3), reduce_scope=(1, 10),
                    msg="点击商品标签页失败"),
            MockTap("tag=a@@text()=我的宝贝", before_delay=(2, 3), after_delay=(2, 3),
                    msg="点击我的宝贝标签页失败")
        ])

    def set_view_condition(self, target_product: TargetProduct):
        """
        设置页面相关条件
        :param target_product 目标商品
        :return:
        """
        input_e = self.page("x://input[@id='queryItemId']")
        Input(input_e, "输入商品标题", vals=target_product.product_id,
              before_delay=(1, 3), after_delay=(1, 3))()
        ActionChains(self.page).key_down(Keys.ENTER)
        time.sleep(3)
        web_page_util.wait_ele_disappear(self.page, ".next-loading-tip", 30)
        # self.page.wait.set_targets("taobao.com", is_regex=False)
        # print(self.page.wait.data_packets())
